from typing import Optional
from dataclasses import dataclass
import time
from collections import OrderedDict
from src.config.settings import TRANSACTION_TIMEOUT, MAX_TRANSACTIONS_CACHE

@dataclass
class Transaction:
    """事务对象"""
    query_type: str
    timestamp: float
    
    @property
    def is_expired(self) -> bool:
        """检查事务是否过期"""
        return time.time() - self.timestamp > TRANSACTION_TIMEOUT

class TimeOrderedCache(OrderedDict):
    """基于时间戳排序的缓存实现"""
    
    def __init__(self, maxsize: int = 1000):
        super().__init__()
        self.maxsize = maxsize
    
    def __setitem__(self, key, value: Transaction):
        """插入新事务时，按时间戳排序
        
        较早的时间戳会被放在前面，便于过期清理
        """
        if len(self) >= self.maxsize:
            # 缓存已满时，检查并清理过期事务
            self.cleanup_expired()
            # 如果清理后仍然满了，删除最早的事务
            if len(self) >= self.maxsize:
                oldest = next(iter(self))
                del self[oldest]
        
        super().__setitem__(key, value)
        # 根据时间戳重新排序
        items = sorted(self.items(), key=lambda x: x[1].timestamp)
        self.clear()
        for k, v in items:
            super().__setitem__(k, v)
    
    def cleanup_expired(self) -> None:
        """清理过期事务"""
        current_time = time.time()
        # 由于按时间排序，可以在遇到第一个未过期事务时停止
        expired_keys = []
        for key, transaction in self.items():
            if transaction.is_expired:
                expired_keys.append(key)
            else:
                break
        for key in expired_keys:
            del self[key]

class TransactionHolder:
    """事务持有者，用于管理DHT网络中的事务"""
    
    def __init__(self, maxsize: int = MAX_TRANSACTIONS_CACHE):
        """初始化事务持有者
        
        Args:
            maxsize: 最大缓存事务数量
        """
        self._transactions = TimeOrderedCache(maxsize=maxsize)

    def add_transaction(self, transaction_id: str, query_type: str) -> None:
        """添加新事务
        
        Args:
            transaction_id: 事务ID
            query_type: 查询类型
        """
        self._transactions[transaction_id] = Transaction(
            query_type=query_type,
            timestamp=time.time()
        )

    def get_transaction_type(self, transaction_id: str) -> str:
        """获取事务类型
        
        Args:
            transaction_id: 事务ID
            
        Returns:
            QueryType: 查询类型
            
        Raises:
            KeyError: 事务ID不存在时抛出
        """
        if transaction_id in self._transactions:
            return self._transactions[transaction_id].query_type
        raise KeyError(f"Transaction {transaction_id} not found")

    def get_transaction(self, transaction_id: str) -> Optional[Transaction]:
        """获取事务对象
        
        Args:
            transaction_id: 事务ID
            
        Returns:
            Optional[Transaction]: 事务对象，不存在则返回None
        """
        return self._transactions.get(transaction_id)

    def remove_transaction(self, transaction_id: str) -> None:
        """移除事务
        
        Args:
            transaction_id: 事务ID
        """
        self._transactions.pop(transaction_id, None)

    def cleanup_expired(self) -> None:
        """清理过期事务"""
        self._transactions.cleanup_expired()

    def has_transaction(self, transaction_id: str) -> bool:
        """检查事务是否存在
        
        Args:
            transaction_id: 事务ID
            
        Returns:
            bool: 事务是否存在
        """
        return transaction_id in self._transactions